Skip to content

Conversation

@elnelson575
Copy link
Contributor

@elnelson575 elnelson575 commented Nov 17, 2025

Fixes #1249

Toolbar Input Selects should:

  • Be single select with selectize=False
  • Be slim enough to fit in a card header without altering the height
  • Use the default behavior for dropdowns
  • Have hover and select highlighting in light mode and in dark mode
  • Accomodate all methods of specifying choices
Screenshot 2025-11-24 at 4 54 04 PM Screenshot 2025-11-24 at 4 53 36 PM
library(shiny)
library(bslib)

ui <- page_fillable(
  tags$head(
    tags$link(rel = "stylesheet", type = "text/css", href = "styles.css")
  ),
  card(
    card_header(
      "Card 1 header",
      toolbar(
        align = "right",
        shiny::downloadLink("download", "Download"),
        toolbar_input_select(
          id = "select",
          choices = c("Option 1", "Option 2", "Option 3"),
          selected = "Option 2"
        ),
        toolbar_input_select(
          id = "select_state",
          choices = list(
            `East Coast` = list("NY", "NJ", "CT"),
            `West Coast` = list("WA", "OR", "CA"),
            `Midwest` = list("MN", "WI", "IA")
          ),
          selected = "NY"
        ),
        input_dark_mode(id = "togglesm", class = "btn-xs border-0")
      )
    ),
    p("Card 1 body"),
    sliderInput("slider", "Slider", 0, 10, 5),
    max_height = "500px",
    card_footer(
      toolbar(
        align = "left",
        toolbar_input_select(
          id = "select_footer",
          choices = c("A" = "a", "B" = "b", "C" = "c"),
          selected = "B"
        )
      )
    )
  ),
  toolbar(
    align = "right",
    actionButton("test", NULL, icon = icon("calendar"), class = "btn-sm"),
    actionButton("test2", NULL, icon = icon("pencil"), class = "btn-sm")
  )
)

server <- function(input, output) {}


shinyApp(ui = ui, server = server)

elnelson575 and others added 30 commits November 3, 2025 11:02
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
@elnelson575 elnelson575 changed the title Feat/toolbar input select feat: Add toolbar input select Nov 24, 2025
@elnelson575 elnelson575 marked this pull request as ready for review November 24, 2025 21:57
flex-direction: row;
align-items: center;
align-self: stretch;
min-height: 2.5rem;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only to match what we currently have in the buttons PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this includes both min-height and padding-block

.bslib-toolbar {
display: flex;
align-items: center;
gap: 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with these changes to toolbar.scss for the .bslib-toolbar (Also just to match what's in buttons)

@gadenbuie
Copy link
Member

I'm not sure if the screenshot in the PR description reflects the current state, but my first reaction is that the horizontal padding feels imbalanced

image

select {
appearance: auto;
padding-block: 3px; // Decreased to slim down select to fit in header
/* .form-controls takes away the drop-down arrow, this ensures it shows up */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I understand what this comment is saying, but I'm not sure. Some things to clarify:

  1. Which .form-controls? Do you mean Bootstrap's rule, Shiny's rule, or another rule in bslib?
  2. I'm pretty sure it refers to the drop-down arrow, but I'm not sure what this refers to. I think you could probably re-order this sentence a bit to avoid two adjacent implicit references.

Comment on lines +49 to +58
#' @param choices List of values to select from. If elements of the list are
#' named, then that name - rather than the value - is displayed to the user.
#' It's also possible to group related inputs by providing a named list whose
#' elements are (either named or unnamed) lists, vectors, or factors. In this
#' case, the outermost names will be used as the group labels (leveraging the
#' `<optgroup>` HTML tag) for the elements in the respective sublist.
#' @param selected The initially selected value. If not specified then defaults
#' to the first value.
#' @param width The width of the input, e.g. '400px', or '100%'; see
#' [validateCssUnit()].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably sufficient; it looks like this documentation was copied from selectInput() anyway.

Suggested change
#' @param choices List of values to select from. If elements of the list are
#' named, then that name - rather than the value - is displayed to the user.
#' It's also possible to group related inputs by providing a named list whose
#' elements are (either named or unnamed) lists, vectors, or factors. In this
#' case, the outermost names will be used as the group labels (leveraging the
#' `<optgroup>` HTML tag) for the elements in the respective sublist.
#' @param selected The initially selected value. If not specified then defaults
#' to the first value.
#' @param width The width of the input, e.g. '400px', or '100%'; see
#' [validateCssUnit()].
#' @inheritParams shiny::selectInput

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to keep documentation local to toolbar_input_select() -- width might be one case -- you can keep the @param docs here.

class = "bslib-toolbar-input-select form-select-sm",
shiny::selectInput(
id,
label = NULL, # Removed for slimline input component
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to keep label but use it for accessibility markup

Comment on lines +68 to +71
width = NULL
) {
htmltools::div(
class = "bslib-toolbar-input-select form-select-sm",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might want to allow ..., check that they're all named arguments (i.e. they are all attributes), and then let people add attributes to the outer container.

Suggested change
width = NULL
) {
htmltools::div(
class = "bslib-toolbar-input-select form-select-sm",
width = NULL,
...
) {
rlang::check_dots_named()
htmltools::div(
class = "bslib-toolbar-input-select form-select-sm",
...,

selected = selected,
multiple = FALSE,
selectize = FALSE,
width = width
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size = NULL is the default for selectInput() and usually I wouldn't include it here, but if it's set you get a very different select input so it's worth setting this to ensure it doesn't accidentally change on us later.

Suggested change
width = width
width = width,
size = NULL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants